﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Linq;

namespace ThreadDemo
{
    public class Custom
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Address { get; set; }
    }

    public class ParallelDemo
    {
        private Stopwatch stopWatch = new Stopwatch();

        #region Invoke 并行执行

        private void Run1()
        {
            Thread.Sleep(2000);
            Console.WriteLine("Task 1 is cost 2 sec");
        }

        private void Run2()
        {
            Thread.Sleep(3000);
            Console.WriteLine("Task 2 is cost 3 sec");
        }

        public void ParallelInvokeMethod()
        {
            stopWatch.Start();
            Parallel.Invoke(Run1, Run2);
            stopWatch.Stop();
            Console.WriteLine("Parallel run " + stopWatch.ElapsedMilliseconds + " ms.");

            stopWatch.Restart();

            Run1();
            Run2();
            stopWatch.Stop();
            Console.WriteLine("Normal run " + stopWatch.ElapsedMilliseconds + " ms.");

        }

        #endregion

        #region MyRegion

        public void ParallelForMethod()
        {

            Parallel.For(0, 100, (i, state) =>
            {
                //中途退出
                if (i == 99)
                {
                    state.Stop();
                    return;
                }
                Console.WriteLine("迭代次数：{0},任务ID:{1},线程ID:{2}", i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
            });

        }

        #endregion

        #region ForEach

        public void ParallelForEachMethod()
        {
            string[] data = { "str1", "str2", "str3" };
            ParallelLoopResult result = Parallel.ForEach(data, (str, state) =>
            {
                Console.WriteLine(str);
            });

            Console.WriteLine("是否完成:{0}", result.IsCompleted);
            Console.WriteLine("最低迭代:{0}", result.LowestBreakIteration);

        }

        #endregion

        #region 线程安全并行执行

        /// <summary>
        /// 线程安全集合使用(并排序)
        /// </summary>
        public void ConcurrentBagMethod()
        {
            ConcurrentBag<int> list = new ConcurrentBag<int>();

            Parallel.For(0, 100, i =>
            {
                list.Add(i);
            });
            Console.WriteLine("ConcurrentBag's  Count is {0}", list.Count);
            //分组
            list.ToLookup(i => i).ToArray();

            foreach (var item in list)
            {
                Console.WriteLine(item);
            }
            List<int> a = new List<int>();
        }

        /// <summary>
        /// Parallel Linq的用法及性能
        /// </summary>
        public void TestLinqSpeed()
        {
            Stopwatch sw = new Stopwatch();

            ConcurrentBag<Custom> customs = new ConcurrentBag<Custom>();

            for (int i = 0; i < 200000; i++)
            {
                customs.Add(new Custom() { Name = "Jack", Age = 21, Address = "NewYork" });
                customs.Add(new Custom() { Name = "Jime", Age = 26, Address = "China" });
                customs.Add(new Custom() { Name = "Tina", Age = 29, Address = "ShangHai" });
                customs.Add(new Custom() { Name = "Luo", Age = 30, Address = "Beijing" });
                customs.Add(new Custom() { Name = "Wang", Age = 60, Address = "Guangdong" });
                customs.Add(new Custom() { Name = "Feng", Age = 25, Address = "YunNan" });
            }
            sw.Start();
            var result = customs.Where(s => s.Age > 21).ToList();
            sw.Stop();
            Console.WriteLine("Linq time is {0}.", sw.ElapsedMilliseconds);

            sw.Restart();

            sw.Start();
            var result2 = customs.AsParallel().Where(s => s.Age > 21).ToList();
            sw.Stop();

            Console.WriteLine("Parallel Linq time is {0}.", sw.ElapsedMilliseconds);

        }


        #endregion
    }
}